﻿using Azure.AI.TextAnalytics;
using Moq;
using MvvmHelpers;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TabbedTemplate.Models;
using TabbedTemplate.Services;
using TabbedTemplate.ViewModels;

namespace UnitTest.ViewModels
{
    public class TestUserHomePageViewModel
    {
        [Test]
        public async Task TestPageAppearingCommand()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var punchinfoStorageMock = new Mock<IPunchInfoStorage>();
            var punchinfoStorage = punchinfoStorageMock.Object;
            await punchinfoStorage.PunchInfoStorageInitializeAsync();
            var favoriteStorageMock = new Mock<IFavoriteStorage>();
            var favoriteStorage = favoriteStorageMock.Object;
            await favoriteStorage.InitializeAsync();
            var store = new Store();
            var storeStorageMock = new Mock<IStoreStorage>();
            storeStorageMock.Setup(p => p.GetStoreByStoreUidAsync("123"))
                .ReturnsAsync(store);
            var storeStorage = storeStorageMock.Object;
            await storeStorage.UserCacheInitializeAsync();
            var userHomePageViewModel =
                new UserHomePageViewModel(favoriteStorage, storeStorage, null, punchinfoStorage, null, mockPreferenceStorage);
            var punchInfoList = new List<PunchInfo>();
            punchinfoStorageMock.Setup(p => p.GetAllPunchInfosAsync()).ReturnsAsync(punchInfoList);
            var favoriteList = new List<Favorite>();
            var time = DateTime.Now.Ticks;
            favoriteList.Add(new Favorite { StoreUid = "123", Timestamp = time });
            favoriteStorageMock.Setup(p => p.GetFavoritesAsync()).ReturnsAsync(favoriteList);
            await userHomePageViewModel.PageAppearingCommandFunction();
            Assert.AreEqual(userHomePageViewModel.PunchRecordCollection.Select(p => p).ToList(), punchInfoList);
            Assert.AreEqual(userHomePageViewModel.StoreFavoriteCollection.Count, 1);
        }

        [Test]
        public async Task TestStoreCheckOutCommand()
        {
            var punchNavigationServiceMock = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var userHomePageViewModel =
                new UserHomePageViewModel(null, null, mockPunchNavigationService, null, null, null);
            await userHomePageViewModel.StoreCheckOutCommandFunction();
            punchNavigationServiceMock.Verify(p => p.UserPageNavigationToAsync(
                ContentNavigationConstant.StoreCollectionsPage), Times.Once);
        }
        [Test]
        public async Task TestPunchInfoCheckOutCommand()
        {
            var punchNavigationServiceMock = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;


            ObservableRangeCollection<PunchTimeStampParameter> collection =
               new ObservableRangeCollection<PunchTimeStampParameter>();
            var userHomePageViewModel =
                    new UserHomePageViewModel(null, null, mockPunchNavigationService, null, null, null);
            userHomePageViewModel.PunchRecordCollection = collection;
            await userHomePageViewModel.PunchInfoCheckOutCommandFunction();
            punchNavigationServiceMock.Verify(p => p.UserPageNavigationToAsync(
                ContentNavigationConstant.MyPunchesPage, collection), Times.Once);
        }
        [Test]
        public async Task TestStoreTappedCommand()
        {
            var punchNavigationServiceMock = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var userHomePageViewModel =
                new UserHomePageViewModel(null, null, mockPunchNavigationService, null, null, null);
            Store store = new Store();
            await userHomePageViewModel.StoreTappedCommandFunction(store);
            punchNavigationServiceMock.Verify(p => p.NavigateToAsync(
                ContentNavigationConstant.StorePunchesPage, store), Times.Once);
        }

        [Test]
        public async Task TestSyncCommand()
        {
            var punchNavigationServiceMock = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var userHomePageViewModel =
                new UserHomePageViewModel(null, null, mockPunchNavigationService, null, null, null);
            await userHomePageViewModel.SyncCommandFunction();
            punchNavigationServiceMock.Verify(p => p.UserPageNavigationToAsync(ContentNavigationConstant.SyncPage)
                , Times.Once);
        }

        [Test]
        public async Task TestCTapPunchCommandFunction()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var punchNavigationServiceMock =
                new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var userHomePageViewModel = new UserHomePageViewModel(null, null,
                mockPunchNavigationService, null, null, mockPreferenceStorage);

            var punchTimeStampParameter = new PunchTimeStampParameter();
            await userHomePageViewModel.CTapPunchCommandFunction(
                punchTimeStampParameter);

            punchNavigationServiceMock.Verify(p => p.NavigateToPunchViewPage(punchTimeStampParameter), Times.Once);
        }

        [Test]
        public async Task TestConvertParameterAnalysisResultIsNullNotHasCache()
        {
            var p1 = new PunchInfo { Store_Uid = "123", Content = "测试", Timestamp = 123 };
            var punchRecordCollection =
                new ObservableRangeCollection<PunchTimeStampParameter> {
                    new PunchTimeStampParameter{PunchInfo = new PunchInfo{Timestamp = 345}},
                    new PunchTimeStampParameter{PunchInfo = new PunchInfo{Timestamp = 234}},
                    new PunchTimeStampParameter{PunchInfo = new PunchInfo{Timestamp = 345}}
                };
            var temp = (DocumentSentiment)null;
            var store = new Store();
            var storeStorageMock = new Mock<IStoreStorage>();
            storeStorageMock.Setup(p => p.GetStoreByStoreUidAsync(p1.Store_Uid))
                .ReturnsAsync(store);
            var mockStoreStorage = storeStorageMock.Object;
            var textAnalysisServiceMock = new Mock<ITextAnalysisService>();
            textAnalysisServiceMock
                .Setup(p => p.AnalysisEmotionAsync(p1.Content)).ReturnsAsync(temp);
            var mockTextAnalysisService = textAnalysisServiceMock.Object;
            var userHomePageViewModel = new UserHomePageViewModel(null,
                mockStoreStorage, null, null, mockTextAnalysisService, null);
            userHomePageViewModel.PunchRecordCollection = punchRecordCollection;
            var res = await userHomePageViewModel.ConvertParameter(p1);
            Assert.IsTrue(res.Scores.Neutral == Convert.ToInt32(100));
        }

        [Test]
        public async Task TestConvertParameterAnalysisResultHasCache()
        {
            var p1 = new PunchInfo { Store_Uid = "123", Content = "测试", Timestamp = 123 };
            var punchRecordCollection =
                new ObservableRangeCollection<PunchTimeStampParameter> {
                    new PunchTimeStampParameter{PunchInfo = new PunchInfo{Timestamp = 123}},
                    new PunchTimeStampParameter{PunchInfo = new PunchInfo{Timestamp = 234}},
                    new PunchTimeStampParameter{PunchInfo = new PunchInfo{Timestamp = 345}}
                };
            var temp = (DocumentSentiment)null;
            var store = new Store();
            var storeStorageMock = new Mock<IStoreStorage>();
            storeStorageMock.Setup(p => p.GetStoreByStoreUidAsync(p1.Store_Uid))
                .ReturnsAsync(store);
            var mockStoreStorage = storeStorageMock.Object;
            var textAnalysisServiceMock = new Mock<ITextAnalysisService>();
            textAnalysisServiceMock
                .Setup(p => p.AnalysisEmotionAsync(p1.Content)).ReturnsAsync(temp);
            var mockTextAnalysisService = textAnalysisServiceMock.Object;
            var userHomePageViewModel = new UserHomePageViewModel(null,
                mockStoreStorage, null, null, mockTextAnalysisService, null);
            userHomePageViewModel.PunchRecordCollection = punchRecordCollection;
            var res = await userHomePageViewModel.ConvertParameter(p1);
            Assert.IsTrue(res.Scores == null);
        }

        [Test]
        public async Task TestCTapStoreCommandFunction()
        {
            var store = new Store();
            var dateTime = new DateTime();
            var favorite = new Favorite();
            var p = new StoreFavorite(store, favorite, dateTime);

            var punchNavigationService = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationService.Object;

            var userHomePageViewModel =
                new UserHomePageViewModel(null, null, mockPunchNavigationService, null, null, null);
            await userHomePageViewModel.CTapStoreCommandFunction(p);
            punchNavigationService.Verify(p => p.UserPageNavigationToAsync(ContentNavigationConstant.StorePunchesPage, store), Times.Once);
        }
    }
}
